package com.example.bolt;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

import org.joor.Reflect;

import com.alipay.remoting.BizContext;
import com.alipay.remoting.InvokeContext;
import com.alipay.remoting.rpc.protocol.SyncUserProcessor;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;

/**
 * 同步请求处理器
 * https://github.com/sofastack/sofa-bolt/blob/master/src/test/java/com/alipay/remoting/rpc/common/SimpleServerUserProcessor.java
 * 
 * 自定义的业务逻辑用户处理器
 * 注意：
 * 对于所有的请求数据的类型，都必须有 UserProcessor 可以处理（感兴趣），
 * 否则将抛出 RpcServerException 异常，类似于 "RpcServerException：No user processor found for request: java.lang.String"
 */
public class MyServerUserProcessor extends SyncUserProcessor<MyRequest<?>> {
	private CountDownLatch      latch          = new CountDownLatch(1);
	//new ThreadPoolExecutor(1, 3, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(4), new NamedThreadFactory("Request-process-pool"));

    @Override
    public Object handleRequest(BizContext bizCtx, MyRequest<?> request) throws Exception {
        MyResponse response = new MyResponse();
        if (request != null) {
            System.out.println("recive request"+request);
            response.setResp("from server -> " + request.getReq());
            
//            bizCtx.getInvokeContext()
            Long waittime = (Long) bizCtx.getInvokeContext().get(InvokeContext.BOLT_PROCESS_WAIT_TIME);

            
            if(request.getCommand().equals("userCommand")) {
//            	UserDTO userDto = (UserDTO) request.getParams();
            	Object userDto = Convert.convertByClassName(request.getClsName(),request.getParams());
            	System.err.println(request.getClsName());
            	System.err.println(JSONUtil.toJsonPrettyStr(userDto));
            	
            	//强制转换 可以使用
            	//https://droidyue.com/blog/2017/01/09/joor-examples/
//            	Reflect.onClass(request.getClsName());
//            	
            	Map<String, Reflect> fields = Reflect.on(userDto).fields();
//            	Map<String, Reflect> fields = Reflect.onClass(Class.forName(request.getClsName())).fields();
            	List<String> names = fields.keySet().stream().collect(Collectors.toList());
            	for (String name : names) {
					System.err.println("field:"+name+"; value="+Reflect.on(userDto).get(name));
					Reflect tReflect = fields.get(name);
					System.err.println(tReflect.type().getName());
				}
            	
            	//TODO 在此处进行请求分发 放入线程池中进行处理 可以根据command 获取指定的bean并发调用
            	
            }
        }
        return response;
    }

    /**
     * 指定感兴趣的请求数据类型，该 UserProcessor 只对感兴趣的请求类型的数据进行处理；
     * 假设 除了需要处理 MyRequest 类型的数据，还要处理 java.lang.String 类型，有两种方式：
     * 1、再提供一个 UserProcessor 实现类，其 interest() 返回 java.lang.String.class.getName()
     * 2、使用 MultiInterestUserProcessor 实现类，可以为一个 UserProcessor 指定 List<String> multiInterest()
     */
    @Override
    public String interest() {
        return MyRequest.class.getName();
    }
}